
import 'package:kq_flutter_core_widget/utils/ex/kq_ex.dart';

import 'core/executor.dart';
import 'core/group_key.dart';
import 'core/monitor.dart';

///合并执行代码，主要用到接口调用上，
///只监测接口执行过程，不涉及接口回调参数等处理。
///以最开始执行的接口开始回调[onStart]方法，
///以最后执行完成的接口回调[onFinish]方法。
///当第一个回调开始了，并已回调完成了，表示整个接口执行完毕，
///当第一个接口执行完毕后，还没开始执行第二个接口，则即使他们有共同的[GroupKey]，
///他们也不能在一个处理周期中处理，我们把一个同一个[GroupKey]下执行的[onStart]和[onFinish]，
///表示一个处理周期。
class CombineExecutor {
  ///执行的对象保存
  final Map<GroupKey, List<Monitor>> _combines = {};

  ///Executor 保存
  final List<Executor> _executors = [];

  final Function(GroupKey key)? onStart;
  final Function(GroupKey key)? onFinish;

  CombineExecutor({this.onStart, this.onFinish});

  _executor(GroupKey key) {
    Executor executor = Executor(key);
    if (!_executors.contains(executor)) {
      _executors.add(executor);
      onStart?.call(key);

      executor.start(callback: (key) {
        List<Monitor> combines = _getCombines(key);
        bool flag = true;
        for (Monitor combineMonitor in combines) {
          if (!combineMonitor.isFinish() && !combineMonitor.isError()) {
            flag = false;
            break;
          }
        }

        //表示最后一个都已执行完成
        if (flag) {
          executor.stop(callback: (key) {
            onFinish?.call(key);
            _clearCombine(key);
            _executors.remove(executor);
          });
        }
      });
    }
  }

  ///停止，在退出界面时调用
  stop() {
    for (Executor executor in _executors) {
      executor.stop();
    }
    _executors.clear();
    _clearAllCombine();
  }

  ///获取合并执行观察者，
  ///设置到请求逻辑中。
  Monitor getCombine(GroupKey key) {
    Monitor combineMonitor = Monitor();
    _addCombine(key, combineMonitor);
    _executor(key);
    return combineMonitor;
  }

  ///新增一个CombineMonitor
  _addCombine(GroupKey key, Monitor combine) {
    if (key.isMonitor) {
      if (_combines.containsKey(key)) {
        List<Monitor>? combines = _combines[key];
        combines ??= [];
        if (!combines.contains(combine)) {
          combines.add(combine);
        }
      } else {
        _combines.putIfAbsent(key, () => [combine]);
      }
    }
  }

  List<Monitor> _getCombines(GroupKey key) {
    if (_isEmptyCombine(key)) {
      return [];
    } else {
      return _combines[key]!;
    }
  }

  ///CombineMonitor是否为空
  _isEmptyCombine(GroupKey key) {
    return !_combines.containsKey(key) || _combines[key].isNullOrEmpty;
  }

  _clearCombine(GroupKey key) {
    _combines.remove(key);
  }

  ///清除全部的CombineMonitor
  _clearAllCombine() {
    _combines.clear();
  }
}

///测试
class Test {
  test() {
    ///创建一个GroupKey，改key可用于一组需要调用的接口上
    GroupKey groupKey = GroupKey();

    ///创建对象
    CombineExecutor executor = CombineExecutor(
      onStart: (key) {
        ///print("执行了onStart");
      },
      onFinish: (key) {
        if (key == groupKey) {
          ///print("执行了onFinish");
        }
      },
    );

    ///获取CombineMonitor 传入到接口调用中
    Monitor monitor = executor.getCombine(groupKey);

    ///模拟异步对Monitor进行操作
    Future.delayed(const Duration(seconds: 2), () {
      monitor.onFinish();
    });

    ///退出界面
    executor.stop();
  }
}
